use std::time::Duration;

use tokio::{process::Command, time};

use snmp_agent::config::update_snmp_global;
use snmp_agent::{config, data::DeviceInfo};

/// POLICY='{"version": "2c", "community": "public", "frequency": 3, "host": "10.30.99.12", "collect_type": "router"}' cargo run
#[tokio::main]
async fn main() {
    tracing_subscriber::fmt::init();
    let config_str = std::env::var("POLICY").unwrap();
    let snmp_config: config::SnmpConfig = serde_json::from_str(&config_str).unwrap();
    tracing::info!("snmp with config {snmp_config:?}");
    let mut interval = time::interval(Duration::from_secs(snmp_config.frequency));
    interval.set_missed_tick_behavior(time::MissedTickBehavior::Skip);
    update_snmp_global(snmp_config.clone()).await;

    'outside: loop {
        interval.tick().await;
        let mut value = String::new();
        for oid in &snmp_config.oid_list {
            let args = [
                "-v",
                &snmp_config.version,
                "-c",
                &snmp_config.community,
                &snmp_config.host,
                oid,
                "-Cc",
            ]
            .iter()
            .map(|x| x.to_string())
            .collect::<Vec<String>>();

            // snmpwalk -v 2c -c public 192.168.1.229 .1.3
            #[cfg(unix)]
            let filepath = "./snmpwalk";
            #[cfg(windows)]
            let filepath = "snmpwalk.exe";
            let output = Command::new(filepath).args(&args).output().await.unwrap();
            if !output.status.success() {
                let stderr = String::from_utf8(output.stderr).unwrap();
                tracing::error!("failed with error {stderr}");
                break 'outside;
            }
            let stdout = String::from_utf8(output.stdout).unwrap();
            value += stdout.as_str();
        }
        println!(
            "{}",
            serde_json::json!(DeviceInfo::new(value.as_str()).await)
        );
    }
}
